/*自身对应的.h文件*/
#include "drv_mipi_touch.h"

/*程序内部对应的.h文件*/
#include "log.h"

/*外部库对应的.h文件*/
#include <libevdev-1.0/libevdev/libevdev.h>

/*系统.h文件*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

#define TOUCH_FB "/dev/input/event2"

/* 需要从板子上拷贝libevdev.so到lib/下 */
static int g_touch_fb = -1;
static struct libevdev *g_touch_dev = NULL;

static struct touch_data
{
	uint16_t x;
	uint16_t y;
	bool is_press;	//0 release 1 press
} g_cur_touch_data = {
	.is_press = 0,
	.x = 0,
	.y = 0,
};

/***************************************************************
 * Name:	 touch_get_new_data()
 * Input : void
 * Output: x、y触控坐标
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 获取触控坐标
 ***************************************************************/
static void touch_get_new_data(uint16_t* x, uint16_t *y)
{
	*x = g_cur_touch_data.x;
	*y = g_cur_touch_data.y;
}

/***************************************************************
 * Name:	 touch_update_thread()
 * Input : NULL
 * Output: void
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 触控更新线程
 ***************************************************************/
void* touch_update_thread(void* arg)
{
	/*触控设备没初始化直接退出*/
	if(g_touch_dev == NULL)
	{
		LOG_ERROR("TOUCH: g_touch_dev == NULL\r\n");
		return NULL;
	}

	while (1)
	{
		struct input_event ev;
		/*分析一个事件*/
		int rc = libevdev_next_event(g_touch_dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
		if(rc == LIBEVDEV_READ_STATUS_SUCCESS)
		{
			if(ev.type == EV_ABS)				//触控事件
			{
				/*保存坐标信息*/
				if(ev.code == ABS_MT_POSITION_X)
				{
					g_cur_touch_data.x = ev.value;
				}
				else if(ev.code == ABS_MT_POSITION_Y)
				{
					g_cur_touch_data.y = ev.value;
				}
			}
			else if(ev.type == EV_KEY)	//按下动作
			{
				/*保存按下抬起动作*/
				g_cur_touch_data.is_press = ev.value == 0 ? false : true;
			}
			else if(ev.type == EV_SYN)	//一包数据传输完成
			{
				
			}
		}
	}
}

/***************************************************************
 * Name:	 touch_update_thread_init()
 * Input : NULL
 * Output: void
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 触控更新线程初始化
 ***************************************************************/
static int touch_update_thread_init(void)
{
	pthread_t thread_id;
	pthread_attr_t attr;
	int res = 0;
	
	/*初始化线程属性*/
	res = pthread_attr_init(&attr);
	if (res != 0)
	{
		LOG_ERROR("pthread_attr_init fail\r\n");
		return -1;
	}

	/*设置为分离线程*/
	res = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (res != 0)
	{
		LOG_ERROR("pthread_attr_setdetachstate failed\r\n");
		pthread_attr_destroy(&attr);
		return -1;
	}

	/*创建线程，线程为test_thread函数*/
	res = pthread_create(&thread_id, &attr, touch_update_thread, NULL);
	if(res != 0)
	{
		LOG_ERROR("create thread fail\r\n");
		pthread_attr_destroy(&attr);
		return -1;
	}

	/*销毁线程属性对象*/
	pthread_attr_destroy(&attr);

	return 0;
}

/***************************************************************
 * Name:	 drv_mipi_touch_init()
 * Input : NULL
 * Output: 0成功 <0失败
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 触控初始化
 ***************************************************************/
int drv_mipi_touch_init(void)
{
	/*打开输入设备*/
	g_touch_fb = open(TOUCH_FB, O_RDONLY | O_NONBLOCK);
	if(g_touch_fb < 0)
	{
		LOG_ERROR("Failed to open mipi touch\r\n");
		return -1;
	}

	/*初始化libevdev*/
	int rc = libevdev_new_from_fd(g_touch_fb, &g_touch_dev);
	if(rc < 0)
	{
		LOG_ERROR("Failed to init libevdev (%s)\n", strerror(-rc));
		close(g_touch_fb);
		return -1;
	}
	
	touch_update_thread_init();
	
	LOG_DEBUG("touch device name: %s\n", libevdev_get_name(g_touch_dev));
	
	return 0;
}

/***************************************************************
 * Name:	 drv_mipi_touch_restore()
 * Input : NULL
 * Output: void
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 触控注销
 ***************************************************************/
void drv_mipi_touch_restore(void)
{
	if(g_touch_dev != NULL)
	{
		libevdev_free(g_touch_dev);
	}

	if(g_touch_fb > 0)
	{
		close(g_touch_fb);
	}
}

/***************************************************************
 * Name:	 drv_mipi_touch_is_press()
 * Input : void
 * Output: void
 * Return: 1按下 0释放
 * Author: hwl
 * Revise: V1.0
 * Description: 触控是否按下
 ***************************************************************/
bool drv_mipi_touch_is_press(void)
{
	return g_cur_touch_data.is_press;
}

/***************************************************************
 * Name:	 drv_mipi_touch_get_data()
 * Input : void
 * Output: x、y触控坐标
 * Return: void
 * Author: hwl
 * Revise: V1.0
 * Description: 获取触控坐标
 ***************************************************************/
void drv_mipi_touch_get_data(uint16_t* x, uint16_t* y)
{
	touch_get_new_data(x, y);
}